package cn.hanfeng.taskservice.runnable;

import cn.hanfeng.taskservice.utils.SpringContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * 定时任务Runnable
 *
 * @author hanfeng 2020/8/26 9:40
 * @version 0.0.1
 */
public class SchedulingRunnable implements Runnable {

    private static final Logger LOGGER = LoggerFactory.getLogger(SchedulingRunnable.class);

    private String beanName;

    private String methodName;

    private String params;

    private String taskSign;

    private String paramsClassType;

    /**
     *
     * @param taskSign
     * @param beanName
     * @param methodName
     */
    public SchedulingRunnable(String taskSign, String beanName, String methodName) {
        this(taskSign, beanName, methodName, null, "java.lang.String");
    }

    /**
     *
     * @param taskSign
     * @param beanName
     * @param methodName
     * @param params
     * @param paramsClassType
     */
    public SchedulingRunnable(String taskSign, String beanName, String methodName, String params, String paramsClassType) {
        this.taskSign = taskSign;
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
        this.paramsClassType = paramsClassType;
    }

    @Override
    public void run() {
        LOGGER.info("定时任务执行, 开始");
        LOGGER.info("定时任务执行参数: bean:{}, 方法:{}, 参数:{}", beanName, methodName, params);
        long startTime = System.currentTimeMillis();

        try {
            Object target = SpringContextUtils.getBean(beanName);

            Method method = null;
            if (StringUtils.isNotEmpty(params)) {
                method = target.getClass().getDeclaredMethod(methodName, String.class);
            } else {
                method = target.getClass().getDeclaredMethod(methodName);
            }

            ReflectionUtils.makeAccessible(method);
            if (StringUtils.isNotEmpty(params)) {
                method.invoke(target, params);
            } else {
                method.invoke(target);
            }
        } catch (Exception ex) {
            LOGGER.error("定时任务执行异常 ", ex);
        }

        long times = System.currentTimeMillis() - startTime;
        LOGGER.info("定时任务执行, 结束. 耗时:{} 毫秒", times);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        SchedulingRunnable that = (SchedulingRunnable) o;
        if (params == null) {
            return beanName.equals(that.beanName) &&
                    methodName.equals(that.methodName) &&
                    that.params == null;
        }

        return beanName.equals(that.beanName) &&
                methodName.equals(that.methodName) &&
                params.equals(that.params);
    }

    @Override
    public int hashCode() {
        if (params == null) {
            return Objects.hash(beanName, methodName);
        }

        return Objects.hash(beanName, methodName, params);
    }

    /**
     * Gets the value of taskSign.
     *
     * @return the value of taskSign
     */
    public String getTaskSign() {
        return taskSign;
    }
}
